package com.jwb.pub.model;

import javax.activation.MimetypesFileTypeMap;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;

public class FileInfo {

	private  String filePath;	
	private  String fileName;
	private  String fileCrc32;
	private  String fileSize;
	private  String contentType;
	private  String extName;	
	private  InputStream  Inputstream;
	

	private static String getContentType(File f){
		String contentType = "";
		try{
			contentType = new MimetypesFileTypeMap().getContentType(f);
		}catch(Exception e){
			e.printStackTrace();
		}
		return contentType;
	}
	
	private  static String  getFileCRCCode(InputStream Inputstream)
	{	CRC32 crc32 = new CRC32();
		try {		
			for (CheckedInputStream checkedinputstream = new CheckedInputStream(Inputstream, crc32);
		            checkedinputstream.read() != -1;) {
		        	
		    }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
      
       return Long.toHexString(crc32.getValue());   
	}
	
	public static FileInfo getFileInfo(String filePath)
	{		
		FileInfo info = null;
		File file = new File(filePath);
		if(file.exists()&&file.isFile()){
			try{
				info = new FileInfo();
				String name = file.getName();
				info.setFileName(name);
				info.setFilePath(filePath);
				info.setExtName(name.indexOf(".")>-1?name.split("\\.")[1]:"");
				info.setFileSize(String.valueOf(file.length()));
				info.setContentType(getContentType(file));
				InputStream is = new FileInputStream(file); 
				info.setInputstream(is);
				info.setFileCrc32(getFileCRCCode(is));
			}catch(Exception e){
				e.printStackTrace();
				info =null;
			}
		}		
		
		return info;  
	}
	
	/**
	 * size 0  不拆分
	 * 拆分文件行程分块分拣列表 
	 */
	 
	public static List<FileInfo>  getFileInfoList(FileInfo fileInfo, int size)
	{
		List<FileInfo> list = null;
		if(fileInfo!=null){
			list = new ArrayList<>();
			if(size==0){
				list.add(fileInfo);
			}else if(size>0){
//				FileInfo fi = new FileInfo();
//				byte[] content = new byte[fileInfo.getFileSize()];
//				InputStream is = fileInfo.getInputstream();
				String contentType = fileInfo.getContentType();
				String ext = fileInfo.getExtName();
				String name = fileInfo.getFileName();
				String path = fileInfo.getFilePath();
				
				try{
					List<File> files = spliteFile(name,ext,path, size);
					for(File f:files){
						FileInfo fi = new FileInfo();
						fi.setContentType(contentType);
						fi.setExtName(ext);
						fi.setFileName(f.getName());
						InputStream is = new FileInputStream(f);
						fi.setInputstream(is);
						fi.setFileCrc32(getFileCRCCode(is));
						fi.setFilePath(f.getPath());
						fi.setFileSize(String.valueOf(f.length()));		
						list.add(fi);
					}		
				}catch(Exception e){
					e.printStackTrace();
					list = null;
				}
			}					
		}		
		return list;
	}
	
	
	private static List<File> spliteFile(String name,String ext,String filePath,int size){
		List<File> files = new ArrayList<>();
		try{
			String root = filePath.substring(0, filePath.lastIndexOf(name));
			String prefix = name.substring(0,name.lastIndexOf("."+ext));
			String joint = "_";
			List<String> fpaths  = new ArrayList<>();
			// root + prefix+joint+ index+"."+ext
			
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
			byte[] bytes = new byte[size];
			int length = -1;
			int idx = 1;
			while((length =bis.read(bytes))>-1){
				String fpath =root+prefix+joint+idx+"."+ext;
				fpaths.add(fpath);
				try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fpath))){
					bos.write(bytes,0,length);
					idx++;
				}catch (Exception e) {
					e.printStackTrace();
				}				
			}
			bis.close();
			if(!fpaths.isEmpty()){
	        	for(String path:fpaths){
	        		File f = new File(path);
	        		if(f.exists()&&f.isFile()){
	        			files.add(f);
	        		}	        		
	        	}	        	
	        }        		
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return files;
	}
	
	
	
	/**
	 * size 0  不拆分
	 * 拆分文件行程分块分拣列表 
	 */
	 
	public  List<FileInfo>  getFileInfoList(String  filePath, int size)
	{
		FileInfo fi = getFileInfo(filePath);
		return getFileInfoList(fi, size);
	}
	
	
	
	
    public static String saveInfoFile(List<FileInfo> fileInfoList)
	{
    	FileInfo result = new FileInfo();
    	if(fileInfoList.size()>0){
    		try{
	    		FileInfo info = fileInfoList.get(0);
	    		String name = info.getFileName();
	    		String root = info.getFilePath().substring(0,info.getFilePath().lastIndexOf(name));
//	    		String path = root+name.split("_")[0]+"."+info.getExtName();
	    		String path = root+name.split("_")[0]+"_new."+info.getExtName();
	    		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
	    		for(FileInfo fi:fileInfoList){
	    			try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fi.getFilePath()))){
	    				byte[] bytes = new byte[2*1024*1024];
	    				int length = -1;
	    				while((length=bis.read(bytes))>-1){
	    					bos.write(bytes,0,length);
	    				}
	    				bos.flush();
	    			}catch (Exception e) {
						e.printStackTrace();
					}	    			
	    		}
	    		bos.close();
    		
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    		
    	}  		    		
	   
		return result.toString();
	}

        
    
	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getFileCrc32() {
		return fileCrc32;
	}

	public void setFileCrc32(String fileCrc32) {
		this.fileCrc32 = fileCrc32;
	}

	public String getFileSize() {
		return fileSize;
	}

	public void setFileSize(String fileSize) {
		this.fileSize = fileSize;
	}

	public String getContentType() {
		return contentType;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getExtName() {
		return extName;
	}

	public void setExtName(String extName) {
		this.extName = extName;
	}

	public InputStream getInputstream() {
		return Inputstream;
	}

	public void setInputstream(InputStream inputstream) {
		Inputstream = inputstream;
	}
    
    

	@Override
	public String toString() {
		return "FileInfo [filePath=" + filePath + ", fileName=" + fileName
				+ ", fileCrc32=" + fileCrc32 + ", fileSize=" + fileSize
				+ ", contentType=" + contentType + ", extName=" + extName
				+ ", Inputstream=" + Inputstream + "]";
	}

	public static void main(String[] args){
		String path = "D:\\video\\test.mp4";
		FileInfo fi =  getFileInfo(path);
		System.out.println(fi);
		List<FileInfo> list = getFileInfoList(fi, 500000);
		saveInfoFile(list);
	}
	
	
	
}
